package com.esb.transport.protocal;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson.JSON;

public class FutureContext {
	
	private static Log logger = LogFactory.getLog(FutureContext.class);
	
	private static final Map<Long, Future<Response>> FUTURES = new ConcurrentHashMap<Long, Future<Response>>();
	
	private static final Executor executor = Executors.newFixedThreadPool(3);
	
	private static Callable<Long> CALLABLE = new Callable<Long>(){
		@Override
		public void call(Long id) {
			FutureContext.cancel(id);
		}
	};
	
	public static Future<Response> sent(Invocation message) {
		Future<Response> future = new Future<Response>(message.getId(), CALLABLE);
		FUTURES.put(message.getId(), future);
		return future;
	}

	public static void cancel(Long id) {
		logger.warn("the message("+id+") is cancelled!");
		FUTURES.remove(id);
	}
	
	public static void received(final Response reponse) {
		logger.debug("received message("+reponse.getId()+")");
		final Future<Response> future = FUTURES.remove(reponse.getId());
		if(future==null){
			logger.warn(JSON.toJSONString(reponse) + "is omited!");
			return;
		}
		executor.execute(new Runnable(){
			@Override
			public void run() {
				future.set(reponse);
			}
		});
		
	}
}
